package test;

import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.awt.image.ImageObserver;

import javax.imageio.ImageIO;

final class Splash extends Frame {
	private static final long serialVersionUID = 1L;
	private String fImageId;
	private MediaTracker fMediaTracker;
	private Image fImage;
	private static final ImageObserver NO_OBSERVER = null; 
	private static final int IMAGE_ID = 0;

	/**
	 * Construct using an image for the splash screen.
	 *  
	 * @param aImageId must have content, and is used by  
	 * {@link Class#getResource(java.lang.String)} to retrieve the splash screen image.
	 */
	public Splash(String aImageId) {
		/* 
		 * Implementation Note
		 * Args.checkForContent is not called here, in an attempt to minimize 
		 * class loading.
		 */
		if ( aImageId == null || aImageId.trim().length() == 0 ){
			throw new IllegalArgumentException("Image Id does not have content.");
		}
		this.fImageId = aImageId;
	}

	/**
	 * Show the splash screen to the end user.
	 *
	 * <P>Once this method returns, the splash screen is realized, which means 
	 * that almost all work on the splash screen should proceed through the event 
	 * dispatch thread. In particular, any call to <tt>dispose</tt> for the 
	 * splash screen must be performed in the event dispatch thread.
	 */
	void splash(){
		initImageAndTracker();
		setSize(fImage.getWidth(NO_OBSERVER), fImage.getHeight(NO_OBSERVER));
		center();
		fMediaTracker.addImage(fImage, IMAGE_ID);
		try {
			fMediaTracker.waitForID(IMAGE_ID);
		}
		catch(InterruptedException ex){
			System.out.println("Cannot track image load.");
		}

		new SplashWindow(this,fImage);
	}

	private void initImageAndTracker(){
		fMediaTracker = new MediaTracker(this);
		//URL imageURL = SplashScreen.class.getResource(fImageId);
		//fImage = Toolkit.getDefaultToolkit().getImage(imageURL);
		try {
			this.fImage = ImageIO.read(new File(fImageId));
		} catch (IOException e) {}
	}

	/**
	 * Centers the frame on the screen.
	 *
	 *<P>This centering service is more or less in {@link hirondelle.stocks.util.ui.UiUtil}; 
	 * this duplication is justified only because the use of  
	 * {@link hirondelle.stocks.util.ui.UiUtil} would entail more class loading, which is 
	 * not desirable for a splash screen.
	 */
	private void center(){
		Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
		Rectangle frame = getBounds();
		setLocation((screen.width - frame.width)/2, (screen.height - frame.height)/2);
	}

	private class SplashWindow extends Window {
		private static final long serialVersionUID = 1L;
		SplashWindow(Frame aParent, Image aImage) {
			super(aParent);
			fImage = aImage;
			setSize(fImage.getWidth(NO_OBSERVER), fImage.getHeight(NO_OBSERVER));
			Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
			Rectangle window = getBounds();
			setLocation((screen.width - window.width) / 2,(screen.height - window.height)/2);
			setVisible(true);
		}
		public void paint(Graphics graphics) {
			if (fImage != null) {
				graphics.drawImage(fImage,0,0,this);
			}
		}
		private Image fImage;
	}

	/**
	 * Developer test harness shows the splash screen for a fixed length of 
	 * time, without launching the full application.
	 */
	private static void main(String... aArgs){
		Splash splashScreen = new Splash("img/splash.gif");
		splashScreen.splash();
		try {
			Thread.sleep(2000);
		}
		catch(InterruptedException ex) {
			System.out.println(ex);
		}
		System.exit(0);
	}
}